package com.hongrui.util.sequencenumber;

import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;;

/**
 * <p>Title: </p>
 *
 * <p>Description:������Ź������֡�</p>
 *
 * <p>Copyright: </p>
 *
 * <p>Company: </p>
 *
 * @author codeslave
 */
public abstract class AbstractGeneral {
	private Connection connection = null;
	private Statement stmt = null;
	private ResultSet rs = null;
	private String sql;
	
	/**
	 * ���캯��
	 */
	public AbstractGeneral() {
  }

	/**
	 * ���캯��
	 * @param connection Connection:��ݿ�l�Ӷ���
	 */
  public AbstractGeneral(Connection connection) {
	  this.connection = connection;
  }
  
  /**
   * ȡ����ݿ�l�Ӷ���
   * @return Connection:��ݿ�l�Ӷ���
   */
  public Connection getConnection(){
  	return connection;
  }
  
  /**
   * ������ݿ�l�Ӷ���
   * @param connection Connection:��ݿ�l�Ӷ���
   */
  public void setConnection(Connection connection){
  	this.connection = connection;
  }
  
  /**
   * ȡ��sql��䡣
   * @return Connection:sql��䡣
   */
  protected String getSql(){
  	return sql;
  }
  
  /**
   * ����sql��䡣
   * @param sql String:sql�����
   */
  protected void setSql(String sql){
  	this.sql = sql;
  }
  
  /**
   * ȡ�ñ��(����ݿ��޹أ�head + ����ʱ�䣻�������DOC20070101120000)��
   * @param head String:���ͷ�����ݣ�����ʱ��Ϊnull����
   * @return String:��š�
   */
  public String getGeneralNumber(String head) {
  	return headJoinDate(head, "yyyyMMddhhmmss");
  }
  
  /**
   * ȡ�����(������)��
   * @param maxValue long:���ֵ��
   * @return String:��š�
   */
	protected String getSequenceNumber(long maxValue) throws SequenceNumberException{
		try {
			stmt = getConnection().createStatement();
      String sequenceNumber = "";
      rs = stmt.executeQuery(getSql());
      rs.next();
      long currNumber = rs.getLong(1);
      if (currNumber < 1) {
      	sequenceNumber += "1";
      }
      else {
      	if(currNumber >= maxValue){throw new SequenceNumberException("�Ѿ��ﵽ�趨�����ֵ,û������µ����!");}
      	if(currNumber == Long.MAX_VALUE){throw new SequenceNumberException("�Ѿ��ﵽLong�͵����ֵ,û������µ����!");}
      	sequenceNumber = Long.toString(++currNumber);
      }
      return sequenceNumber;
    }
    catch (Exception e) {
    	throw new SequenceNumberException(e.toString(),e.getCause());
    }
    finally{
    	clear();
    }
	}
	
	/**
   * ȡ�����(�ַ���)��
   * @param head String:���ͷ������(����ʱ��Ϊnull)��
   * @param digitNum int:���λ��(ֻ������Ų���λ���磺DOC000001Ϊ6λ)��
   * @param fillChar char:����ַ�(��:'0','A'������ʱ��Ϊnull��Ĭ��Ϊ'0'��ע:����������1-9)��
   * @return String:��š�
   */
	protected String getSequenceNumber(String head, int digitNum, char fillChar) throws SequenceNumberException {
		try {
			//fillChar����Ϊ1-9�������ַ�
			if(Character.isDigit(fillChar) && fillChar != '0'){throw new SequenceNumberException("����ַ���Ϊ1-9�������ַ�!");}
			stmt = getConnection().createStatement();
      String sequenceNumber = "";
      rs = stmt.executeQuery(getSql());
      rs.next();
      long currNumber = Long.valueOf(filtrateNonDigit(rs.getString(1))).longValue();
      if (currNumber < 1) {
        sequenceNumber = (head == null?"":head) + fillSequenceNumber("1", digitNum, fillChar);
      } 
      else {
      	if(currNumber == Long.MAX_VALUE){throw new SequenceNumberException("�Ѿ��ﵽLong�͵����ֵ,û������µ����!");}
      	sequenceNumber = Long.toString(++currNumber);
      	sequenceNumber = fillSequenceNumber(sequenceNumber, digitNum, fillChar);
      	if(checkOverflow(sequenceNumber, digitNum)){throw new SequenceNumberException("�Ѿ��ﵽ�趨�����λ��,û������µ����!");}
      	sequenceNumber = (head == null?"":head) + sequenceNumber;
      }
      return sequenceNumber;
    }
		catch (Exception e) {
    	throw new SequenceNumberException(e.toString(),e.getCause());
    }
    finally{
    	clear();
    }
	}
  
  /**
   * �����ŵĿ�ȱ���֡�
   * @param sequenceNumber String:��š�
   * @param digitNum int:���λ��
   * @param fillChar char:����ַ�
   * @return String:������ַ�
   */
  protected String fillSequenceNumber(String sequenceNumber, int digitNum, char fillChar) {
    String sequenceNumber_Temp = sequenceNumber;
  	int digitOld = sequenceNumber_Temp.length();
    for (int i = 0; i < digitNum - digitOld; i++) {
    	sequenceNumber_Temp = fillChar + sequenceNumber_Temp;
    }
    return sequenceNumber_Temp;
  }
  
  /**
   * ���ַ���ʽ��������Ƿ�����λ���ǲ�����ͬ��
   * @param sequenceNumber String:��š�
   * @param digitNum int:���λ��
   * @return boolean:���ؽ��δ����false������true��
   */
  protected boolean checkOverflow(String sequenceNumber, int digitNum) {
    if (sequenceNumber.length() <= digitNum) {
      return false;
    }
    return true;
  }
  
  /**
   * ���˷������ַ�
   * @param sequenceNumber String:��š�
   * @return boolean:���������ַ�
   */
  protected String filtrateNonDigit(String sequenceNumber) {
  	int length = sequenceNumber.length();
    String sequenceNumber_Temp = "";
    for(int i = 0; i < length; i++){
    	if(Character.isDigit(sequenceNumber.charAt(i))){
    		sequenceNumber_Temp += sequenceNumber.charAt(i);
    	}
    }
    return sequenceNumber_Temp;
  }
  
  /**
   * ���ͷ�����뵱ǰ���ڡ�
   * @param head String:���ͷ�����ݡ�
   * @param format String:���ڸ�ʽ��
   * @return String:�����µ����ͷ��(head + ����)��
   */
  protected String headJoinDate(String head, String format){
  	java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(format);
    String head_Date = sdf.format(new java.util.Date());
    String head_Temp = (head == null?"":head) + head_Date;
    return head_Temp;
  }
  
  /**
   * ��Դ���?
   */
  protected void clear() {
  	if(rs != null) {
  		try {
  			rs.close();
  			rs = null;
  		}catch (Exception e) {
  	    e.printStackTrace();
  	    rs = null;
  	  }
  	}
  	if(stmt != null) {
  		try {
  			stmt.close();
  			stmt = null;
  		}catch (Exception e) {
  	    e.printStackTrace();
  	    stmt = null;
  	  }
  	}
  }
  
  /**
   * �رա�
   */
  public void close() {
  	if(getConnection() != null) {
  		try {
  			getConnection().close();
  			setConnection(null);
  		}catch (Exception e) {
  	    e.printStackTrace();
  	    setConnection(null);
  	  }
  	}
  }

}